/**
 * visTopoClustering.h
 * ubuntu8.04,g++4.3.2
 * 18/3/2009,VISUALIZATION_CGCAD_THSS_THU_BJ
 * Author : Xinlai,Lu
 *
 * Potential bugs:
 * The points on integration curves used to build the kd-tree may be not closed, ie. 
 * they may not reach the boundary and leave an opening, which may lead to that the
 * searching of sources in a domain access another different domain.
 *
 * Modification History:
 *
 */
#ifndef VIS_FLOW_GUIDED
#define VIS_FLOW_GUIDED

#include "ucdinputfile.h"
#include "visKDTree.h"
#include "visFlowTopology.h"

namespace visualization
{
struct positionAndDistance
{
	Point coordinates;
	double distance;
};

class visFlowGuided : public visFlowTopology
{
public:
	visFlowGuided(Model *mdl) : visFlowTopology(mdl),
															m_NearestPointForSaddles(NULL),
															m_NearestPoints(NULL),
															m_IntervalSaddles(NULL),
															m_IntervalCriticalPoints(NULL)
	{
	}
	visFlowGuided() : visFlowTopology()
	{
	}

	~visFlowGuided()
	{
		delete []m_NearestPointForSaddles;
		delete []m_NearestPoints;
		delete []m_IntervalSaddles;
		delete []m_IntervalCriticalPoints;
	}

	/**
	 * Group critical points.
	 */
	void groupCriticalPoints();

	/**
	 * Calculate the least distance for each critical points with
	 * the result saved in m_NearestPointForSaddle and m_NearestPoints.
	 */
	void initializeTemplates();

	/**
	 * According to the results from initializeTemplate(), sources for
	 * streamlines can be determined.
	 */
	void makeSources();

	/**
	 * Integrate to get the streamlines.
	 */
	intgResults *integrate();

	/**
	 *
	 */
	void processSaddlesAndSaddles(size_t i, size_t j);
	void processSaddlesAndOthers(size_t i, size_t j);
	void processOthersAndOthers(size_t i, size_t j);
	void processOthersAndSaddles(size_t i, size_t j);

	vector<Point> getTemplateSources(){return m_Sources;}
	vector<criticalPoint> getCriticalPoints(){ return criticalPoints; }

private:
	// Save the nearest points for a critical points.
	positionAndDistance *m_NearestPointForSaddles;
	positionAndDistance *m_NearestPoints;

	// Sources generated by templates.
	vector<Point> m_Sources;
	double *m_IntervalSaddles;
	double *m_IntervalCriticalPoints;
};
}
#endif
